from pyasn1.codec.der import encoder, decoder
from pyasn1_modules import rfc5652, rfc5280
from pyasn1.type import univ, useful
from cryptography.hazmat.primitives import serialization, hashes
from cryptography.hazmat.primitives.asymmetric import padding

from issuer_and_serial_number import build_issuer_name

# 加载私钥和证书
with open('../rsa/private_key.der', 'rb') as f:
    private_key = serialization.load_der_private_key(f.read(), password=None)
with open('../rsa/certificate.der', 'rb') as f:
    cert_der = f.read()

# 1. 构建 SignedData
signed_data = rfc5652.SignedData()
print(type(signed_data['version']))
signed_data['version'] = univ.Integer(1)
print(signed_data.prettyPrint())
signed_data['version'] = 'v1'
print(signed_data.prettyPrint())

# 2. 设置摘要算法（SHA-256）
digest_algo = rfc5652.DigestAlgorithmIdentifier()
digest_algo['algorithm'] = univ.ObjectIdentifier('2.16.840.1.101.3.4.2.1')  # SHA-256 OID
digestAlgorithms = []
digestAlgorithms.append(digest_algo)
signed_data['digestAlgorithms'] = univ.SetOf().setComponents(digest_algo)

# 3. 原始内容
content_info = rfc5652.ContentInfo()
content_info['contentType'] = rfc5652.id_data  # OID: 1.2.840.113549.1.7.1
content_info['content'] = univ.OctetString(b'Hello PKCS#7')
signed_data['encapContentInfo'] = content_info  # 注意字段名改为 encapContentInfo

# 4. 添加证书
certificate, _ = decoder.decode(
    cert_der,
    asn1Spec=rfc5280.Certificate()  # 指定 ASN.1 规范
)
# 方法一
# certificate_set = rfc5652.CertificateSet()
# certificate_set[0]['certificate']=certificate
# signed_data['certificates'] = certificate_set # 会报错
# 方法二
# cert_choice = rfc5652.CertificateChoices()
# cert_choice['certificate'] = certificate
# certificate_set = []
# certificate_set.append(cert_choice)
# signed_data['certificates'] = univ.SetOf().setComponents(certificate_set)
signed_data['certificates'][0]['certificate'] = certificate

# 5. 构建 SignerInfo
signer_info = rfc5652.SignerInfo()
signer_info['version'] = univ.Integer(1)

# 颁发者与序列号
issuer_and_serial = rfc5652.IssuerAndSerialNumber()
issuer_and_serial['issuer'] = build_issuer_name(
        country='CN',
        organization='Example Company',
        organizational_unit='IT Department',
        common_name='Example CA'
    )
issuer_and_serial['serialNumber'] = univ.Integer(123456789)
sig_ident = rfc5652.SignerIdentifier()
sig_ident['issuerAndSerialNumber'] = issuer_and_serial
signer_info['sid'] = sig_ident  # 字段名改为 sid

# 摘要算法
signer_info['digestAlgorithm'] = digest_algo

# 签名算法
signing_algo = rfc5652.SignatureAlgorithmIdentifier()
signing_algo['algorithm'] = univ.ObjectIdentifier('1.2.840.113549.1.1.11')  # sha256WithRSA
signer_info['signatureAlgorithm'] = signing_algo

# 生成签名
signature = private_key.sign(
    b'Hello PKCS#7',
    padding.PKCS1v15(),
    hashes.SHA256()
)
signer_info['signature'] = univ.OctetString(signature)

# 6. 添加 SignerInfo 到 SignedData
signed_data['signerInfos'] = rfc5652.SignerInfos().setComponents(signer_info)

# 7. 封装到 ContentInfo
outer_content_info = rfc5652.ContentInfo()
outer_content_info['contentType'] = rfc5652.id_signedData  # OID: 1.2.840.113549.1.7.2
outer_content_info['content'] = signed_data

# 8. 生成 DER 文件
der_bytes = encoder.encode(outer_content_info)
with open('signed_data.der', 'wb') as f:
    f.write(der_bytes)